我使用gemini提取出了老师视频中展示的文档,非常好。因为老师确实没有给文档,blog里面也搜不到,幸好有了AI,帮我很大的忙。
Install NodeJS and Database 前提是要安装nodejs和某种数据库,因为prisma通常是为关系型数据库构建的,所以NoSQL这些大部分都不能支持,只支持MongoDB。我按照老师的要求,安装了postgresql。
npm init -y ,初始化项目。
npm i --save-dev prisma typescript ts-node @types/node nodemon , Install dependencies
Create tsconfig.json
xxxxxxxxxx91{2 "compilerOptions": {3 "sourceMap": true,4 "outDir": "dist",5 "strict": true,6 "lib": ["esnext"],7 "esModuleInterop": true8 }9}这个是配置typescript相关的。
npx prisma init --datasource-provider postgresql , Initial Prisma project
Connect Database
a. Install VSCode extension for Prisma
b. Also talk about auto formatting and npx prisma format
xxxxxxxxxx131// schema.prisma2datasource db {3 provider = "postgresql"4 url = env("DATABASE_URL")5}67generator client {8 provider = "prisma-client-js"9 output = "../generated/prisma"10}1112// .env13DATABASE_URL="postgresql://postgres:password@localhost:5433/test"这里需要重点讲解一下,datasource db指的是Prisma orm该怎么样连接到数据库管理系统,provider指的是数据库管理系统的类型,可以是mysql、sqlite等等,url指的是连接数据库管理系统的哪一个数据库。
在步骤4执行之后,会生成schema.prisma文件和.env文件,在.env文件里面,有一个DATABASE_URL的变量,这里存放的是数据库的地址。这个地址可以是本地数据库的地址,也可以是云服务器中数据库的地址。

generator的作用是定义代码生成规则,provider指定用哪一个生成器,output自定义生成文件的输出目录。因为prisma的核心是“基于schema自动生成代码”,而generator就是“告诉prisma”要生成什么,怎么生成,生成到哪里“的关键配置。
只有这样配置了,在代码中才能使用PrismaClient,来方便的操作数据库。
url的格式是:postgresql://用户名:密码@主机:端口/数据库名,我的本地用户名默认是postgres,密码是123456,主机是localhost,端口是5432,数据库需要新建,打开powershell,输入psql -h localhost -p 5432 -U postgres,输入密码123456,然后输入create database prisma,这样就生成了一个名称为prisma的数据库。
那么这里的url就写成这样DATABASE_URL="postgresql://postgres:123456@localhost:5432/prisma?schema=public",这里的?schema=public,它的意思是告诉 Prisma(或其他工具):默认使用 public 这个 schema 来查找表和执行查询。这涉及到postgresql的表结构,和MySQL是不一样的,先不用管。


Create User Schema with name
xxxxxxxxxx41model User {2 id Int @id @default(autoincrement())3 name String4}npx prisma migrate dev --name init , Create/Run migration。这一步是为了将定义的model迁移到数据库中去,dev表示只在开发环境做这件事,--name init表示为这次操作设置名称,方便以后查看。
这一步执行之后,会在prisma文件夹里面生成一个migrations文件夹,里面就是迁移文件,这些文件将与postgresql交互并进行用户指定的修改。
与此同时,也对Prisma client进行了更新,这样使用prisma client的时候,就能够用到最新的数据库。

npm install @prisma/client - Install Client (Talk about how this also generates the client as well for us and how this generation happens every time you migrate as well and how you can create this generation your self with npx prisma generate)
创建一个script.ts文件,就可以写代码了。
xxxxxxxxxx151import { PrismaClient } from '@prisma/client'23const prisma = new PrismaClient({ log: ["query"] })45async function main() {6 // ... you will write your Prisma Client queries here7}89main()10 .catch((e) => {11 console.error(e.message)12 })13 .finally(async () => {14 await prisma.$disconnect()15 })await prisma.user.create({ data: { name: "Sally" } }) - Create new user
await prisma.user.findMany() - Get all users
Must have at least one generator but can have more than one
The provider represents what generator to use
a. This can be any NPM library such as a GraphQL generator
String
Boolean
Int
BigInt
Float
Decimal
DateTime
Json
Bytes
Reference to another table (Post)
Unsupported
a. Special case for when you pull a database and it contains types that Prisma does not support
[]
a. Turns the column into a list. When used on a reference type it creates all needed foreign keys and such
b. Can only be used on scalar types if the DB supports it
?
a. Makes a field optional
b. Cannot be used with []
Attributes have two levels
a. Field attributes apply to one field @
b. Block attributes apply to the entire block @@
@id
a. All tables must have an id field or have a unique field
b. Can be combined with @default
i. autoincrement()
ii. uuid()
@@id
a. Used to create composite ids @@id([FirstName, LastName])
@default
a. Can be passed a static value or a function such as now()
@unique - Makes a field unique
@@unique - Makes a combination of fields unique @@unique(authorId, postId)
@@index - Create index on one or more fields @@index(authorId, postId)
@updatedAt - Automatically sets a field to the current time when you update the row
@relation
a. The fields with relation types are not actually in the db
b. One To Many
xxxxxxxxxx101model User {2 id Int @id @default(autoincrement())3 posts Post[]4}56model Post {7 id Int @id @default(autoincrement())8 author User @relation(fields: [authorId], references: [id])9 authorId Int10}c. One To One
xxxxxxxxxx101model User {2 id Int @id @default(autoincrement())3 profile Profile?4}56model Profile {7 id Int @id @default(autoincrement())8 user User @relation(fields: [userId], references: [id])9 userId Int @unique10}d. Many To Many
xxxxxxxxxx91model Post {2id Int @id @default(autoincrement())3categories Category[]4}56model Category {7id Int @id @default(autoincrement())8posts Post[]9}
e. The @relation field must take a field and references value.
i. The field points to the field on the current model
ii. The references points to the field on the other model the field value references
f. If you have multiple relations on the same model you need to pass a name to the references attribute to disambiguate them
xxxxxxxxxx131model User {2id Int @id @default(autoincrement())3writtenPosts Post[] @relation("WrittenPosts")4favoritePosts Post[] @relation("FavoritePosts")5}67model Post {8id Int @id @default(autoincrement())9author User @relation("WrittenPosts", fields: [authorId], references: [id])10authorId Int11favoritedBy User? @relation("FavoritePosts", fields: [favoritedById], references: [id])12favoritedById Int?13}
xxxxxxxxxx91model User {2 id Int @id @default(autoincrement())3 role Role @default(BASIC)4}56enum Role {7 BASIC8 ADMIN9}
xxxxxxxxxx591// This is your Prisma schema file,2// learn more about it in the docs: https://pris.ly/d/prisma-schema34generator client {5 provider = "prisma-client-js"6}78datasource db {9 provider = "sqlite"10 url = env("DATABASE_URL")11}1213model User {14 id String @id @default(uuid())15 isAdmin Boolean @default(false)16 age Int17 name String18 email String @unique19 writtenPosts Post[] @relation("WrittenPosts")20 favoritePosts Post[] @relation("FavoritePosts")21 preferences UserPreference? @relation(fields: [userPreferenceId], references: [id])22 role Role @default(BASIC)23 userPreferenceId String? @unique2425 @@unique([name, age])26 @@index([email])27}2829model UserPreference {30 id String @id @default(uuid())31 emailUpdates Boolean32 user User?33}3435model Post {36 id String @id @default(uuid())37 title String38 averageRating Float // Also talk about BigInt, Decimal, Json, Unsupported, an39 createdAt DateTime @default(now())40 updatedAt DateTime @updatedAt41 author User @relation("WrittenPosts", fields: [authorId], references: [id])42 authorId String43 favoritedBy User? @relation("FavoritePosts", fields: [favoritedById], references: [id])44 favoritedById String?45 categories Category[]4647 // @@id([title, authorId])48}4950model Category {51 id String @id @default(uuid())52 name String @unique53 posts Post[]54}5556enum Role {57 BASIC58 ADMIN59}create
xxxxxxxxxx71const user = await prisma.user.create({2 data: {3 email: 'kyle@test.com',4 name: 'Kyle',5 age: 276 }7})xxxxxxxxxx141const user = await prisma.user.create({2 data: {3 email: 'mike@test.com',4 name: 'Mike',5 age: 16,6 preferences: {7 create: {8 shouldReceiveEmailNotifications: true9 }10 }11 },12 include: { preferences: true }, // Has the ability to nest include/select13 select: { name: true, email: true }14})createMany
xxxxxxxxxx141const user = await prisma.user.createMany({2 data: [3 {4 email: 'sally@test.com',5 name: 'Sally',6 age: 257 },8 {9 email: 'john@test.com',10 name: 'John',11 age: 1212 }13 ]14})findUnique - Can also include/select
xxxxxxxxxx201const user = await prisma.user.findUnique({2 where: {3 email: "kyle@test.com"4 }5})67const user = await prisma.user.findUnique({8 where: {9 id: 110 }11})1213const user = await prisma.user.findUnique({14 where: {15 name_age: {16 name: "Kyle",17 age: 2718 }19 }20})findFirst - Same as findMany but only gets first result
findMany - Can also select/include
a. distinct - Can do distinct queries
b. take / skip - Can do pagination
c. orderBy - Can do sorting
xxxxxxxxxx11const allUsers = await prisma.user.findMany()equals - same as not using an objectnot - { not: { name: "Kyle" } }in - { name: { in: ["Kyle", "Sally"] } }notInlt / ltegt / gtecontains - { email: { contains: "@gmail.com" } }startsWith / endsWithAND - { AND: [{ name: "Kyle" }, { age: 27 }] }ORNOTxxxxxxxxxx141const result = await prisma.user.findMany({2 where: {3 post: {4 every: {5 published: true6 },7 some: {8 content: {9 contains: "Prisma"10 }11 }12 }13 }14})someeverynoneisisNotupdate - Can also include/select
a. Only updates 1 record
b. Must include data and where
xxxxxxxxxx81const updateUser = await prisma.user.update({2 where: {3 email: 'kyle@test.com',4 },5 data: {6 name: 'Kyle Cook',7 },8})increment
decrement
multiply
divide
xxxxxxxxxx81const updatedUser = await prisma.post.update({2 where: { "name": "Kyle" },3 data: {4 age: {5 increment: 16 }7 }8})Should I cover this
https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#nested-writes
updateMany - Same as update but with no select/include
xxxxxxxxxx81const updateUsers = await prisma.user.updateMany({2 where: {3 email: { endsWith: '@test.com' }4 },5 data: {6 role: 'ADMIN',7 },8})delete - Can also select/include
a. Only deletes 1 record
xxxxxxxxxx51const deletedUser = await prisma.user.delete({2 where: {3 email: 'kyle@test.com',4 },5})deleteMany - Can also select/include
a. Only deletes 1 record
xxxxxxxxxx51const deletedUsers = await prisma.user.deleteMany({2 where: {3 age: { gt: 20 }4 },5})